//----------------------------------------------------------------
#include "Miner.h"
#include "Player.h"
#include "World.h"
//----------------------------------------------------------------
Miner::Miner(int iPosX, int iPosY, World* pkWorld, Player* pkPlayer)
:
fTimeSinceLastAction(0),
m_iResourceAmount(0),
m_iPosX(iPosX),
m_iPosY(iPosY),
m_pkWorld(pkWorld),
m_pkPlayer(pkPlayer)
{
	setSpritePos();
}
//----------------------------------------------------------------
Miner::~Miner()
{
}
//----------------------------------------------------------------
void Miner::update(float fTimeBetweenFrames)
{
	fTimeSinceLastAction += fTimeBetweenFrames;
	switch (m_kCurrentState)
	{
		case MinerStates::Idle:
		{
			break;
		}
		case MinerStates::GoingToMine:
		{
			if (fTimeSinceLastAction >= TIME_BETWEEN_ACTIONS)
			{
				m_iCurrentPos += 2;
				m_iPosY = m_kCurrentPath[m_iCurrentPos];
				m_iPosX = m_kCurrentPath[m_iCurrentPos+1];
				setSpritePos();
				fTimeSinceLastAction = 0;
				if(m_iCurrentPos + 2 == m_kCurrentPath.size())
					m_kCurrentState = Minning;
			}
			break;
		}
		case MinerStates::GoingToBase:
		{
			if (fTimeSinceLastAction >= TIME_BETWEEN_ACTIONS)
			{
				m_iCurrentPos += 2;
				m_iPosY = m_kCurrentPath[m_iCurrentPos];
				m_iPosX = m_kCurrentPath[m_iCurrentPos+1];
				setSpritePos();
				fTimeSinceLastAction = 0;
				if(m_iCurrentPos + 2 == m_kCurrentPath.size())
					m_kCurrentState = Unloading;
			}
			break;
		}
		case MinerStates::Minning:
		{
			if (fTimeSinceLastAction >= TIME_BETWEEN_ACTIONS)
			{
				int iAmountMined = MAX_CAPACITY - m_iResourceAmount;
				m_pkWorld->mineNode(m_kResourceType, m_iCurrentNodePosX, m_iCurrentNodePosY, iAmountMined);

				//si no puedo minar mas vuelvo a la base
				if (iAmountMined == 0)
				{
					/*
					switch (m_kResourceType)
					{
						case ResourceList::Gold:
							minerDoAction(GoToMineGold);
							break;
						case ResourceList::Stone:
							minerDoAction(GoToMineStone);
							break;
						case ResourceList::Food:
							minerDoAction(GoToMineFood);
							break;
						case ResourceList::Wood:
							minerDoAction(GoToMineWood);
							break;
					}
					*/
					minerDoAction(GoToBase);
				}

				m_iResourceAmount += iAmountMined;
				cout << "Miner carring: " << m_iResourceAmount << endl;

				if (MAX_CAPACITY == m_iResourceAmount)
					minerDoAction(GoToBase);

				fTimeSinceLastAction = 0;
			}
			break;
		}
		case MinerStates::Unloading:
		{
			if (fTimeSinceLastAction >= TIME_BETWEEN_ACTIONS)
			{
				int iAmountToUnload = min(m_iResourceAmount, MAX_UNLOAD);
				if (iAmountToUnload == 0)
				{
					switch (m_kResourceType)
					{
						case ResourceList::Gold:
							minerDoAction(GoToMineGold);
							break;
						case ResourceList::Stone:
							minerDoAction(GoToMineStone);
							break;
						case ResourceList::Food:
							minerDoAction(GoToMineFood);
							break;
						case ResourceList::Wood:
							minerDoAction(GoToMineWood);
							break;
					}
				}
				else
				{
					m_pkPlayer->addResourceAmount(m_kResourceType, iAmountToUnload);
					m_iResourceAmount -= iAmountToUnload;
					cout << "Miner carring: " << m_iResourceAmount << endl;
				}
				fTimeSinceLastAction = 0;
			}
			break;
		}
	}	
}
//----------------------------------------------------------------
void Miner::minerDoAction(MinerActions kAction)
{
	m_kCurrentPath.clear();
	switch (kAction)
	{
		case MinerActions::StopActions:
			m_kCurrentState = Idle;
			break;
		case MinerActions::GoToBase:
			if (!(m_pkPlayer->getNearestBase(m_kCurrentPath, m_iPosX, m_iPosY)))
			{
				minerDoAction(StopActions);
			}
			else
			{
				m_iCurrentPos = 0;
				m_kCurrentState = GoingToBase;
			}
			break;
		case MinerActions::GoToMineGold:
			if (m_kResourceType != ResourceList::Gold)
				m_iResourceAmount = 0;
			m_kResourceType = ResourceList::Gold;
			if (!(m_pkWorld->getNearestResourceNode(m_kResourceType, m_kCurrentPath, m_iPosX, m_iPosY, m_iCurrentNodePosX, m_iCurrentNodePosY)))
			{
				minerDoAction(StopActions);
			}
			else
			{
				m_iCurrentPos = 0;
				m_kCurrentState = GoingToMine;
			}
			break;
		case MinerActions::GoToMineStone:
			if (m_kResourceType != ResourceList::Stone)
				m_iResourceAmount = 0;
			m_kResourceType = ResourceList::Stone;
			if (!(m_pkWorld->getNearestResourceNode(m_kResourceType, m_kCurrentPath, m_iPosX, m_iPosY, m_iCurrentNodePosX, m_iCurrentNodePosY)))
			{
				minerDoAction(StopActions);
			}
			else
			{
				m_iCurrentPos = 0;
				m_kCurrentState = GoingToMine;
			}
			break;
		case MinerActions::GoToMineFood:
			if (m_kResourceType != ResourceList::Food)
				m_iResourceAmount = 0;
			m_kResourceType = ResourceList::Food;
			if (!(m_pkWorld->getNearestResourceNode(m_kResourceType, m_kCurrentPath, m_iPosX, m_iPosY, m_iCurrentNodePosX, m_iCurrentNodePosY)))
			{
				minerDoAction(StopActions);
			}
			else
			{
				m_iCurrentPos = 0;
				m_kCurrentState = GoingToMine;
			}
			break;
		case MinerActions::GoToMineWood:
			if (m_kResourceType != ResourceList::Wood)
				m_iResourceAmount = 0;
			m_kResourceType = ResourceList::Wood;
			if (!(m_pkWorld->getNearestResourceNode(m_kResourceType, m_kCurrentPath, m_iPosX, m_iPosY, m_iCurrentNodePosX, m_iCurrentNodePosY)))
			{
				minerDoAction(StopActions);
			}
			else
			{
				m_iCurrentPos = 0;
				m_kCurrentState = GoingToMine;
			}
			break;
	}
}
//----------------------------------------------------------------
void Miner::setSpritePos()
{
	int iCols, iRows, iTileHeight, iTileWidth;
	m_pkWorld->getWorldData(iCols, iRows, iTileHeight, iTileWidth);
	float fWorldPosX, fWorldPosY;
	m_pkWorld->getWorldPos(fWorldPosX, fWorldPosY);

	int iIndex = m_iPosY * iRows + m_iPosX;
	float fSpritePosX = (float)((iIndex % iRows));
	float fSpritePosY = (float)(iRows - 1 - (iIndex / iRows));
	fSpritePosX = fSpritePosX * iTileWidth - iTileHeight / 2;
	fSpritePosY = fSpritePosY * iTileHeight - iTileHeight / 2;
	fSpritePosX += fWorldPosX;
	fSpritePosY += fWorldPosY;
	fSpritePosX -= (float)((iRows * iTileWidth) / 2);
	fSpritePosY -= (float)((iCols * iTileHeight) / 2);

	m_pkSprite.setPos(fSpritePosX, fSpritePosY);
}
//----------------------------------------------------------------
